﻿using System;
using Birkelund.QueryStrings.Internals;

namespace Birkelund.QueryStrings.Tokens
{
    /// <summary>
    /// Extension methods
    /// </summary>
    public static class Extensions
    {
        /// <summary>
        /// Obsolete: Use ReadNullIfEmpty instead
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="token"></param>
        /// <param name="uri"></param>
        /// <returns></returns>
        [Obsolete("Use ReadNullIfEmpty instead", true)]
        public static T? NullIfEmpty<T>(this IQueryStringToken<T> token, Uri uri) where T : struct
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Obsolete: Use ReadNullIfEmpty instead
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="token"></param>
        /// <returns></returns>
        [Obsolete("Use ReadNullIfEmpty instead", true)]
        public static T? NullIfEmpty<T>(this IQueryStringToken<T> token) where T : struct
        {
            throw new NotSupportedException();
        }

        #region IQueryStringToken extensions
        /// <summary>
        /// Reads the token value from the provided uri. Return null if the token value is empty or the token is not set.
        /// </summary>
        /// <typeparam name="T">A valuetype</typeparam>
        /// <param name="token">The token</param>
        /// <param name="uri">The uri</param>
        /// <returns>Returns the read value or null</returns>
        public static T? ReadNullIfEmpty<T>(this IQueryStringToken<T> token, Uri uri) where T : struct
        {
            QueryStringReader reader = QueryStringReader.CreateFromUrl(uri);
            if (reader.Exists(token) && !string.IsNullOrEmpty(reader.ReadStringValue(token, UriEncodingMode.HandleEncoding)))
            {
                return token.ReadValue(uri);
            }
            else return null;
        }

        /// <summary>
        /// Reads the token value from the current uri. Return null if the token value is empty or the token is not set.
        /// </summary>
        /// <typeparam name="T">A valuetype</typeparam>
        /// <param name="token">The token</param>
        /// <returns>Returns the read value or null</returns>
        public static T? ReadNullIfEmpty<T>(this IQueryStringToken<T> token) where T : struct
        {
            return ReadNullIfEmpty(token, Common.CurrentUrl);
        }

        //this cannot be made as 'where T : class' as the parameterlist does not differ from above
        /// <summary>
        /// Reads the token value from the provided uri. Return null if the token value is empty or the token is not set.
        /// </summary>
        /// <param name="token">The token</param>
        /// <param name="uri">The uri</param>
        /// <returns>Returns the read value or null</returns>
        public static string ReadNullIfEmpty(this IQueryStringToken<string> token, Uri uri)
        {
            QueryStringReader reader = QueryStringReader.CreateFromUrl(uri);
            if (reader.Exists(token) && !string.IsNullOrEmpty(reader.ReadStringValue(token, UriEncodingMode.HandleEncoding)))
            {
                return token.ReadValue(uri);
            }
            else return null;
        }

        /// <summary>
        /// Reads the token value from the current uri. Return null if the token value is empty or the token is not set.
        /// </summary>
        /// <param name="token">The token</param>
        /// <returns>Returns the read value or null</returns>        
        public static string ReadNullIfEmpty(this IQueryStringToken<string> token)
        {
            return ReadNullIfEmpty(token, Common.CurrentUrl);
        }
        #endregion
    }
}
